﻿using DearlerPlatform.Common;
using DearlerPlatform.Core.DataBaseCommon;
using Newtonsoft.Json.Linq;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace DearlerPlatform.Core.Repository
{
    public class Repository<TEntity> : IRepository<TEntity> where TEntity : class, new()
    {
        private readonly ISqlSugarClient _db;
        public Repository(ISqlSugarClient db)
        {
            this._db = db;
        }

        /// <summary>
        /// 返回所有数据集合
        /// </summary>
        /// <returns></returns>
        public List<TEntity> GetList()
        {
            return _db.Queryable<TEntity>().ToList();
        }
        /// <summary>
        /// 按条件返回数据集合
        /// </summary>
        /// <param name="expression">条件</param>
        /// <returns></returns>
        public List<TEntity> GetList(Expression<Func<TEntity, bool>> expression)
        {
            return _db.Queryable<TEntity>().Where(expression).ToList();
        }
        /// <summary>
        /// 异步返回所有数据集合
        /// </summary>
        /// <returns></returns>
        public async Task<List<TEntity>> GetListAsync()
        {
            return await _db.Queryable<TEntity>().ToListAsync();
        }
        /// <summary>
        /// 异步按条件返回数据集合
        /// </summary>
        /// <param name="expression">条件</param>
        /// <returns></returns>
        public async Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> expression)
        {
            return await _db.Queryable<TEntity>().Where(expression).ToListAsync();
        }

        /// <summary>
        /// 查询单个数据
        /// </summary>
        /// <param name="expression">条件</param>
        /// <returns></returns>
        public TEntity Get(Expression<Func<TEntity, bool>> expression)
        {
            return _db.Queryable<TEntity>().First(expression);
        }
        /// <summary>
        /// 异步查询单个数据
        /// </summary>
        /// <param name="expression">条件</param>
        /// <returns></returns>
        public async Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> expression)
        {
            return await _db.Queryable<TEntity>().FirstAsync(expression);
        }

        /// <summary>
        /// 插入一个实体
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <returns></returns>
        public TEntity Insert(TEntity entity)
        {
            var res = _db.Insertable(entity).ExecuteReturnEntity();
            return res;
        }
        /// <summary>
        /// 异步插入一个实体
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <returns></returns>
        public async Task<TEntity> InsertAsync(TEntity entity)
        {
            var res = await _db.Insertable(entity).ExecuteReturnEntityAsync();
            return res;
        }

        /// <summary>
        /// 批量插入数据
        /// </summary>
        /// <param name="entity">数据集合</param>
        /// <returns>返回数据行数</returns>
        public int Insert(List<TEntity> entity)
        {
            var res = _db.Insertable(entity).ExecuteCommand();
            return res;
        }
        /// <summary>
        /// 异步批量插入数据
        /// </summary>
        /// <param name="entity">数据集合</param>
        /// <returns>返回数据行数</returns>
        public async Task<int> InsertAsync(List<TEntity> entity)
        {
            var res = await _db.Insertable(entity).ExecuteCommandAsync();
            return res;
        }
        /// <summary>
        /// 删除一个实体
        /// </summary>
        /// <param name="id">ID主键</param>
        /// <returns>影响行数</returns>
        public int Delete(long id)
        {
            var res = _db.Deleteable<TEntity>().In(id).ExecuteCommand();
            return res;
        }
        /// <summary>
        /// 异步删除一个实体
        /// </summary>
        /// <param name="id">ID主键</param>
        /// <returns>影响行数</returns>
        public async Task<int> DeleteAsync(long id)
        {
            var res = await _db.Deleteable<TEntity>().In(id).ExecuteCommandAsync();
            return res;
        }
        /// <summary>
        /// 批量删除数据
        /// </summary>
        /// <param name="ids">主键集合</param>
        /// <returns>影响行数</returns>
        public int Delete(long[] ids)
        {
            var res = _db.Deleteable<TEntity>().In(ids).ExecuteCommand();
            return res;
        }
        /// <summary>
        /// 异步批量删除数据
        /// </summary>
        /// <param name="ids">主键集合</param>
        /// <returns>影响行数</returns>
        public async Task<int> DeleteAsync(long[] ids)
        {
            var res = await _db.Deleteable<TEntity>().In(ids).ExecuteCommandAsync();
            return res;
        }
        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="entity">需要更新的实体</param>
        /// <returns>影响行数</returns>
        public int Update(TEntity entity)
        {
            return _db.Updateable(entity).ExecuteCommand();
        }
        /// <summary>
        /// 异步更新数据
        /// </summary>
        /// <param name="entity">需要更新的实体</param>
        /// <returns>影响行数</returns>
        public async Task<int> UpdateAsync(TEntity entity)
        {
            return await _db.Updateable(entity).ExecuteCommandAsync();
        }
        /// <summary>
        /// 批量更新数据
        /// </summary>
        /// <param name="entity">实体集合</param>
        /// <returns>影响行数</returns>
        public int Update(List<TEntity> entity)
        {
            return _db.Updateable(entity).ExecuteCommand();
        }
        /// <summary>
        /// 异步批量更新数据
        /// </summary>
        /// <param name="entity">实体集合</param>
        /// <returns>影响行数</returns>
        public async Task<int> UpdateAsync(List<TEntity> entity)
        {
            return await _db.Updateable(entity).ExecuteCommandAsync();
        }
        /// <summary>
        /// 异步通用单表查询方法
        /// </summary>
        /// <param name="pars">查询参数</param>
        /// <returns>通用返回结果</returns>
        public async Task<CorePageData<List<TEntity>>> GetPageListAsync(QueryParameterBase par)
        {
            CorePageData<List<TEntity>> resList = new CorePageData<List<TEntity>>();
            List<TEntity> data = new List<TEntity>();
            RefAsync<int> total = 0;

            var query = _db.Queryable<TEntity>();
            var keyVPList = new List<KeyValuePair<WhereType, IConditionalModel>>();
            if (par.ConditionalList != null)
            {
                foreach (var item in par.ConditionalList)
                {
                    var keyVP = new KeyValuePair<WhereType, IConditionalModel>(item.Key, new ConditionalModel()
                    {
                        ConditionalType = item.Value.ConditionalType,
                        FieldName = item.Value.FieldName,
                        FieldValue = item.Value.FieldValue,

                    });
                    keyVPList.Add(keyVP);
                }
                IConditionalModel model = new ConditionalTree()
                {
                    ConditionalList = keyVPList
                };
                List<IConditionalModel> conditionalModels = new List<IConditionalModel>();
                conditionalModels.Add(model);
                var list = query.Where(conditionalModels);
            }
            if (par.OrderBys != null)
            {
                foreach (var item in par.OrderBys)
                {
                    query.OrderBy(item.ToSqlFilter());//格式 id asc或者 id desc
                }
            }
            data = await query.ToPageListAsync(par.PageNum, par.PageSize, total);
            resList.Total = total;
            resList.PageNum = par.PageNum;
            resList.PageSize = par.PageSize;
            resList.Data = data;
            return resList;
        }

        ///// <summary>
        ///// 异步通用单表查询方法
        ///// </summary>
        ///// <param name="pars">查询参数</param>
        ///// <returns>通用返回结果</returns>
        //public async Task<PageViewBase<List<TEntity>>> GetPageListTestAsync(QueryParameterBaseTest pars)
        //{
        //    PageViewBase<List<TEntity>> resList = new PageViewBase<List<TEntity>>();
        //    List<TEntity> data = new List<TEntity>();
        //    RefAsync<int> total = 0;


        //    var query = _db.Queryable<TEntity>();
        //    if (pars.Query.Parameters != null)
        //    {
        //        var sugarParamters = pars.Query.Parameters.Select(it => (IConditionalModel)new ConditionalModel()
        //        {
        //            ConditionalType = it.ConditionalType,
        //            FieldName = it.FieldName,
        //            FieldValue = it.FieldValue
        //        }).ToList();
        //        query.Where(sugarParamters);
        //    }
        //    if (pars.Query.OrderBys != null)
        //    {
        //        foreach (var item in pars.Query.OrderBys)
        //        {
        //            query.OrderBy(item.ToSqlFilter());//格式 id asc或者 id desc
        //        }
        //    }
        //    data = await query.ToPageListAsync(pars.PageNum, pars.PageSize, total);
        //    resList.Total = total;
        //    resList.PageNum = pars.PageNum;
        //    resList.PageSize = pars.PageSize;
        //    resList.Data = data;
        //    return resList;
        //}

        /// <summary>
        /// 仓储扩展方法:多表查询通用分页 
        /// 用法  CommonPage(db.Queryable<JoinTable1,JoinTable2>(...).Select(it=new class(){..}).MergeTable(),pars,orderbys,pageIndex,pagesize)
        /// </summary>
        /// <returns></returns>
        public async Task<object> CommonPage<ViewModel>(ISugarQueryable<ViewModel> query, QueryParameterBase pars)
        {
            /*
            //测试代码
            var testqu = new QueryParameterBase();
            //Where条件必须在返回结果里面
            var haha = await _productRepo.CommonPage(_db.Queryable<Products, Productphotos>((p, pr) => p.Sysno == pr.Sysno).Select((p, pr) => new { 
                Sysno = p.Sysno,
                ProductName = p.Productname,
                ProductPhotoUrl = pr.Productphotourl,
                TypeName = p.Typename,
                Id = p.Id
            }).MergeTable(), testqu);
            //测试代码结束
             */
            PageViewBase<List<TEntity>> resList = new PageViewBase<List<TEntity>>();
            List<TEntity> data = new List<TEntity>();
            RefAsync<int> total = 0;

            var keyVPList = new List<KeyValuePair<WhereType, IConditionalModel>>();
            if (pars.ConditionalList != null)
            {
                foreach (var item in pars.ConditionalList)
                {
                    var keyVP = new KeyValuePair<WhereType, IConditionalModel>(item.Key, new ConditionalModel()
                    {
                        ConditionalType = item.Value.ConditionalType,
                        FieldName = item.Value.FieldName,
                        FieldValue = item.Value.FieldValue,

                    });
                    keyVPList.Add(keyVP);
                }
                IConditionalModel model = new ConditionalTree()
                {
                    ConditionalList = keyVPList
                };
                List<IConditionalModel> conditionalModels = new List<IConditionalModel>();
                conditionalModels.Add(model);
                var list = query.Where(conditionalModels);
            }
            if (pars.OrderBys != null)
            {
                foreach (var item in pars.OrderBys)
                {
                    query.OrderBy(item.ToSqlFilter());//格式 id asc或者 id desc
                }
            }

            var result = await query.ToPageListAsync(pars.PageNum, pars.PageSize, total);
            return new
            {
                total = total,
                data = result
            };
        }

        //public List<IConditionalModel> JsonToConditionalModels(string json)
        //{
        //    List<IConditionalModel> conditionalModels = new List<IConditionalModel>();
        //    var jarray = _db.Utilities.DeserializeObject<JArray>(json);
        //    foreach (var item in jarray)
        //    {

        //        if (item.Count() > 0)
        //        {
        //            if (item.ToString().Contains("ConditionalList"))
        //            {
        //                IConditionalModel model = new ConditionalTree()
        //                {
        //                    ConditionalList = GetConditionalList(item)
        //                };
        //                conditionalModels.Add(model);
        //            }
        //            else
        //            {
        //                IConditionalModel conditionalModel = new ConditionalModel()
        //                {
        //                    ConditionalType = (ConditionalType)Convert.ToInt32(item["ConditionalType"].Value<int>()),
        //                    FieldName = item["FieldName"] + "",
        //                    FieldValue = item["FieldValue"].Value<string>() == null ? null : item["FieldValue"].ToString()
        //                };
        //                conditionalModels.Add(conditionalModel);
        //            }
        //        }
        //    }
        //    return conditionalModels;
        //}
        //private static List<KeyValuePair<WhereType, IConditionalModel>> GetConditionalList(JToken item)
        //{
        //    List<KeyValuePair<WhereType, IConditionalModel>> result = new List<KeyValuePair<WhereType, IConditionalModel>>();
        //    var values = item.Values().First();
        //    foreach (var jToken in values)
        //    {
        //        WhereType type = (WhereType)Convert.ToInt32(jToken["Key"].Value<int>());
        //        IConditionalModel conditionalModel = null;
        //        var value = jToken["Value"];
        //        if (value.ToString().Contains("ConditionalList"))
        //        {
        //            conditionalModel = new ConditionalTree()
        //            {
        //                ConditionalList = GetConditionalList(value)
        //            };
        //        }
        //        else
        //        {
        //            conditionalModel = new ConditionalModel()
        //            {
        //                ConditionalType = (ConditionalType)Convert.ToInt32(value["ConditionalType"].Value<int>()),
        //                FieldName = value["FieldName"] + "",
        //                FieldValue = value["FieldValue"].Value<string>() == null ? null : value["FieldValue"].ToString()
        //            };
        //        }
        //        result.Add(new KeyValuePair<WhereType, IConditionalModel>(type, conditionalModel));
        //    }
        //    return result;
        //}

    }
}
   